<template>
  <button class="fx-button" @click="handleButtonClick" :class="handleClassName" :style="buttonStyle">
    <span class="loading animation" v-if="loading">
      <i class="iconfont icon-loading fs14"/>
    </span>
    <span class="loading" v-if="icon!==''">
      <i class="fs14 iconfont" :class="icon"/>
    </span>
    <slot></slot>
  </button>
</template>

<script lang="ts">
import { computed, defineComponent, PropType, SetupContext } from 'vue'
import { ComponentSize, componentSizeArr, ComponentTypes, componentTypesArr } from '@/base/types'

export declare interface ButtonProps {
  type: ComponentTypes | 'text',
  size: ComponentSize | number,
  plain: boolean,
  round: boolean,
  circle: boolean,
  disabled: boolean,
  loading: boolean,
  icon: string
}

export default defineComponent({
  name: 'FxButton',
  emits: ['click'],
  inheritAttrs: true,
  props: {
    // 样式类型
    type: {
      type: String as PropType<ComponentTypes | 'text'>,
      default: '',
      validator (value: string): boolean {
        return [...componentTypesArr, 'text'].includes(value)
      }
    },
    // 大小类型
    size: {
      type: [String, Number] as PropType<ComponentSize | number>,
      default: 'default',
      validator (val: ComponentSize | number): boolean {
        if (typeof val === 'string') return componentSizeArr.includes(val)
        return Number.isInteger(val)
      }
    },
    // 镂空
    plain: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    // 圆角
    round: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    // 圆形
    circle: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    // 禁用
    disabled: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    // 加载
    loading: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    // 图标
    icon: {
      type: String as PropType<string>,
      default: ''
    }
  },
  setup (props: ButtonProps, ctx: SetupContext) {
    // 点击事件
    const handleButtonClick = (ev: MouseEvent): void => {
      if (props.disabled || props.loading) return
      ctx.emit('click', ev)
    }
    // 类名
    const handleClassName = computed(() => {
      const size = typeof props.size === 'string' ? props.size : null
      return [
        size,
        props.type,
        {
          plain: props.plain,
          round: props.round,
          circle: props.circle,
          disabled: props.disabled || props.loading,
          hover: !props.disabled && !props.loading
        }
      ]
    })
    // 按钮样式
    const buttonStyle = computed(() => {
      if (typeof props.size !== 'number') return null
      const size = props.size <= 24 ? 24 : props.size
      return {
        width: props.circle ? `${size}px` : null,
        height: `${size}px`,
        lineHeight: `${size}px`,
        borderRadius: props.round ? `${size / 2}px` : null
      }
    })

    return {
      buttonStyle,
      handleClassName,
      handleButtonClick
    }
  }
})
</script>
